/**
 * Copyright (C) 2011 Domenico Briganti <dometec@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package it.webrules.deploymanager.webapp.controller;

import it.webrules.deploymanager.webapp.auth.AuthenticatedUser;
import it.webrules.deploymanager.webapp.auth.DMPrincipal;
import it.webrules.deploymanager.webapp.exception.AlreadyExistException;
import it.webrules.deploymanager.webapp.exception.NotCreatedException;
import it.webrules.deploymanager.webapp.exception.NotDeletedException;
import it.webrules.deploymanager.webapp.service.ConfigurationService;
import it.webrules.deploymanager.webapp.transentities.ConfigPath;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriBuilder;

import net.java.dev.webdav.jaxrs.methods.MKCOL;

import com.google.inject.Inject;
import com.sun.jersey.spi.resource.PerRequest;

@PerRequest
@Path("services/configtree{subResources:.*}")
public class ConfigTreeController extends BaseController {

	@AuthenticatedUser
	@SuppressWarnings("unused")
	private DMPrincipal user;

	@Inject
	private ConfigurationService configurationService;

	@PathParam("subResources")
	private String path;

	@Inject
	public ConfigTreeController() {
	}

	@GET
	// @ApplicationRolesAllowed({ Constants.ROLE_ADMIN, Constants.ROLE_USER })
	@Produces(MediaType.APPLICATION_JSON)
	public Response get() throws FileNotFoundException {

		path = path.replaceFirst("/", "");

		File file = configurationService.getFileFromPath(path);

		if (file.isFile())
			return Response.ok(file).build();

		UriBuilder baseUriBuilder = uriInfo.getBaseUriBuilder();
		ConfigPath configPath = configurationService.getConfig(path, baseUriBuilder);

		return Response.ok(configPath).build();

	}

	@MKCOL
	// @ApplicationRolesAllowed({ Constants.ROLE_ADMIN })
	public Response createFolder() {

		if (path == null)
			return Response.status(Status.PRECONDITION_FAILED).build();

		try {

			configurationService.createPath(path);

		} catch (AlreadyExistException e) {
			return Response.status(Status.CONFLICT).build();
		} catch (NotCreatedException e) {
			return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getClass().getName()).type(MediaType.TEXT_PLAIN).build();
		}

		return Response.status(Status.CREATED).build();

	}

	@DELETE
	// @ApplicationRolesAllowed({ Constants.ROLE_ADMIN })
	public Response delete() throws IOException {

		if (path == null)
			return Response.status(Status.PRECONDITION_FAILED).build();

		try {

			configurationService.delete(path);

		} catch (NotDeletedException e) {
			return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getClass().getName()).type(MediaType.TEXT_PLAIN).build();
		}

		return Response.noContent().build();

	}

	@PUT
	// @ApplicationRolesAllowed({ Constants.ROLE_ADMIN })
	public Response createConfiguration(InputStream in) {

		if (path == null)
			return Response.status(Status.PRECONDITION_FAILED).build();

		try {

			configurationService.createConfiguration(path, in);

			return Response.created(uriInfo.getAbsolutePath()).build();

		} catch (AlreadyExistException e) {
			return Response.status(Status.CONFLICT).build();
		} catch (IOException e) {
			return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getClass().getName()).type(MediaType.TEXT_PLAIN).build();
		} finally {
			try {
				if (in != null)
					in.close();
			} catch (IOException e) {
				// ignore
			}
		}

	}

	@POST
	// @ApplicationRolesAllowed({ Constants.ROLE_ADMIN })
	public Response updateConfiguration(InputStream in) {

		if (path == null)
			return Response.status(Status.PRECONDITION_FAILED).build();

		try {

			configurationService.updateConfiguration(path, in);

			return Response.ok().build();

		} catch (IOException e) {
			return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getClass().getName()).type(MediaType.TEXT_PLAIN).build();
		} finally {
			try {
				if (in != null)
					in.close();
			} catch (IOException e) {
				// ignore
			}
		}

	}

}
